package com.nowcoder.community.service;

import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class FollowService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserMapper userMapper;

    // 判断userId对应的用户是否已关注idolId对应的用户
    public boolean getFollowStatus(int userId, int idolId) {
        String idolKey = RedisKeyUtil.getIdolKey(userId);
        return redisTemplate.opsForZSet().score(idolKey, idolId) != null;
    }

    // 获取userId对应的用户的关注数
    public long getIdolCount(int userId) {
        String idolKey = RedisKeyUtil.getIdolKey(userId);
        Long count = redisTemplate.opsForZSet().size(idolKey);
        return count != null ? count : 0;
    }

    // 获取userId对应的用户的粉丝数
    public long getFollowerCount(int userId) {
        String followerKey = RedisKeyUtil.getFollowerKey(userId);
        Long count = redisTemplate.opsForZSet().size(followerKey);
        return count != null ? count : 0;
    }

    // 关注或取消关注
    public void follow(int userId, int targetId) {
        redisTemplate.execute(new SessionCallback<Object>() {
            @Override
            public <K, V> Object execute(RedisOperations<K, V> operations) throws DataAccessException {
                String idolKey = RedisKeyUtil.getIdolKey(userId);
                String followerKey = RedisKeyUtil.getFollowerKey(targetId);
                boolean hasFollowed = redisTemplate.opsForZSet().score(idolKey, targetId) != null;

                // 开启事务
                operations.multi();
                if (hasFollowed) {
                    // 已关注过，执行取消关注
                    redisTemplate.opsForZSet().remove(idolKey, targetId);
                    redisTemplate.opsForZSet().remove(followerKey, userId);
                } else {
                    // 没关注，执行关注
                    long currentTime = System.currentTimeMillis();
                    redisTemplate.opsForZSet().add(idolKey, targetId, currentTime);
                    redisTemplate.opsForZSet().add(followerKey, userId, currentTime);
                }

                return operations.exec();
            }
        });
    }

    // 获取userId对应的用户的所有关注以及关注时间
    public List<Map<String, Object>> getIdols(int userId, int offset, int limit) {
        String idolKey = RedisKeyUtil.getIdolKey(userId);
        return this.getIdolsOrFollowers(idolKey, offset, limit);
    }

    // 获取userId对应的用户的所有粉丝以及关注时间
    public List<Map<String, Object>> getFollowers(int userId, int offset, int limit) {
        String followerKey = RedisKeyUtil.getFollowerKey(userId);
        return this.getIdolsOrFollowers(followerKey, offset, limit);
    }

    private List<Map<String, Object>> getIdolsOrFollowers(String key, int offset, int limit) {
        List<Map<String, Object>> list = new ArrayList<>();
        Set<Object> ids = redisTemplate.opsForZSet().reverseRange(key, offset, offset + limit - 1);
        if (ids != null) {
            for (Object id : ids) {
                Map<String, Object> map = new HashMap<>();
                map.put("user", userMapper.selectUserById((Integer) id));
                Double score = redisTemplate.opsForZSet().score(key, id);
                map.put("followTime", new Date(score.longValue()));
                list.add(map);
            }
        }
        return list;
    }

}
